
package com.vdong.redis.data.core;

import com.google.common.base.Optional;
import com.vdong.redis.data.core.json.FastJsonRedisTemplate;
import org.springframework.data.redis.core.RedisTemplate;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * Description: druid connect test
 *
 * @author <a href="mailto:yrh@qtz360.com">yrh</a>
 * @Date Create on 2018年07月27日
 * @since version1.0 Copyright 2018 QTZ All Rights Reserved.
 */
public interface RedisOperator {

    /**
     * key/value操作，根据key获得value
     *
     * @param key String
     * @return Optional<String> Optional.absent() means null
     */
    Optional<String> get(String key);

    /**
     * key/value操作，根据key获得value，并转换成指定class
     *
     * @param key
     * @param clz
     * @return
     */
    <T> Optional<T> get(String key, Class<T> clz);

    /**
     * key/value操作，根据key获得value的列表，并转换成指定class
     *
     * @param key String
     * @param clz Reference E List<E>
     * @return Optional<List               <               E>> Optional.absent() means null
     */
    <E> Optional<List<E>> getForList(String key, Class<E> clz);

    /**
     * key/value操作，根据key设置value
     *
     * @param key   String
     * @param value Object
     */
    void set(String key, Object value);

    /**
     * key/value操作，根据key设置value,设置过期时间
     *
     * @param key
     * @param value
     * @param second
     */
    void set(String key, Object value, long second);

    /**
     * key/value操作，根据key设置value,设置过期时间
     *
     * @param key
     * @param value
     * @param timeout
     * @param unit
     */
    void set(String key, Object value, long timeout, TimeUnit unit);

    /**
     * key/value操作，根据key设置value,只有redis中key不存在时，才插入值
     *
     * @param key   must not be {@literal null}.
     * @param value must not be {@literal null}.
     * @return
     * @see <a href="http://redis.io/commands/setnx">Redis Documentation:
     * SETNX</a>
     */
    Optional<Boolean> setNx(String key, Object value);

    /**
     * key/value操作，根据key设置value,只有redis中key不存在时，才插入值，并设置过期时间
     *
     * @param key     String
     * @param value   object
     * @param seconds timeout seconds
     */
    void setEx(String key, Object value, long seconds);

    /**
     * key/value操作，根据key设置value,只有redis中key不存在时，才插入值，并设置过期时间
     *
     * @param key     String
     * @param value   object
     * @param timeout timeout
     * @param unit    time unit
     */
    void setEx(String key, Object value, long timeout, TimeUnit unit);

    /**
     * 自增1
     *
     * @param key String
     * @return the incred value
     */
    Optional<Long> incr(String key);

    /**
     * 自增指定值
     *
     * @param key   String
     * @param delta increment number
     * @return eht incred value
     */
    Optional<Long> incrBy(String key, final long delta);

    /**
     * 自减指定值
     *
     * @param key
     * @param delta
     * @return
     */
    Optional<Long> decrBy(String key, final long delta);

    /**
     * 设置过期时间
     *
     * @param key     String
     * @param seconds timeout
     * @return
     */
    Optional<Boolean> expire(String key, long seconds);

    /**
     * 设置过期时间
     *
     * @param key     String
     * @param timeout timeout
     * @param unit    time unit
     * @return
     */
    Optional<Boolean> expire(String key, long timeout, TimeUnit unit);

    /**
     * 设置过期时间
     *
     * @param key
     * @param date
     * @return
     */
    public Optional<Boolean> expireAt(String key, Date date);

    /**
     * 删除指定的键
     *
     * @param key
     */
    void del(String key);

    /**
     * 删除指定的多个键
     *
     * @param keys
     */
    void del(String... keys);

    /**
     * 是否存在该键值
     *
     * @param key
     * @return
     */
    Optional<Boolean> hasKey(String key);

    /**
     * 获得map的值
     *
     * @param key   Object
     * @param field String
     * @return the value associated with field, or nil when field is not present
     * in the hash or key does not exist.
     */
    <T> Optional<T> hget(String key, Object field);

    /**
     * 获得map的值
     *
     * @param key
     * @param field
     * @param clz   the value reference T
     * @return the value associated with field, or nil when field is not present
     * in the hash or key does not exist.
     */
    <T> Optional<T> hget(String key, Object field, Class<T> clz);

    /**
     * 获得map的值，list形式
     *
     * @param key
     * @param field
     * @param clz
     * @return
     */
    <E> Optional<List<E>> hgetForList(String key, Object field, Class<E> clz);

    /**
     * 设置map的值
     *
     * @param key
     * @param field
     * @param value
     */
    void hset(String key, Object field, String value);

    /**
     * 设置map的值
     *
     * @param key
     * @param field
     * @param value
     */
    void hset(String key, Object field, Object value);

    /**
     * 设置map的多个值
     *
     * @param key
     * @param hashMap
     */
    void hmset(String key, Map<Object, Object> hashMap);

    /**
     * 删除map的值
     *
     * @param key
     * @param field
     * @return
     */
    Optional<Long> hdel(String key, String field);

    /**
     * 获得RedisTemplate
     *
     * @return
     */
    RedisTemplate<String, Object> getTemplate();

    /**
     * 获得FastJsonRedisTemplate
     *
     * @return
     */
    FastJsonRedisTemplate<String, Object> getFastJsonRedisTemplate();

    /**
     * 忽略redis的异常，如果是，则执行redis下一条命令错误后，将不会抛出异常，但会打印日志 注意，redis命令执行后，会自动失效
     */
    void ignoreRedisException();
}
